#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <string>

using namespace std;

//class Person
//{
//public:
//	Person() { ++_count; }
//protected:
//	string _name; // 姓名
//public:
//	static int _count; // 统计人的个数。
//};
//int Person::_count = 0;
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//class Graduate : public Student
//{
//protected:
//	string _seminarCourse; // 研究科目
//};
//void TestPerson()
//{
//	Student s1;
//	Student s2;
//	Student s3;
//	Graduate s4;
//	cout << " 人数 :" << Person::_count << endl;
//	Student::_count = 0;
//	cout << " 人数 :" << Person::_count << endl;
//}
//
//int main()
//{
//	TestPerson();
//	return 0;
//}

//class Person {
//public:
//	virtual ~Person() { cout << "~Person()" << endl; }
//};
//class Student : public Person {
//public:
//	virtual ~Student() { cout << "~Student()" << endl; }
//};
//// 只有派生类Student的析构函数重写了Person的析构函数，下面的delete对象调用析构函
////数，才能构成多态，才能保证p1和p2指向的对象正确的调用析构函数。
//int main()
//{
//	Person* p1 = new Person;
//	Person* p2 = new Student;
//
//	delete p1;
//	delete p2;
//}


//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Base::Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Base::Func2()" << endl;
//	}
//	void Func3()
//	{
//		cout << "Base::Func3()" << endl;
//	}
//private:
//	int _b = 1;
//};
//class Derive : public Base
//{
//public:
//	virtual void Func1()
//	{
//		
//	}
//
//	virtual void Function() {}
//private:
//	int _d = 2;
//};
//int main()
//{
//	Base b;
//	Derive d;
//	cout << "Derive::Func1()" << endl;
//	return 0;
//}

//auto_ptr
//template<class T>
//class auto_ptr
//{
//public:
//	auto_ptr(T* ptr)
//		:_ptr(ptr)
//	{}
//
//	auto_ptr(auto_ptr<T>& sp)
//		:_ptr(sp.ptr)
//	{
//		//管理权转移
//		sp._ptr = nullptr;
//	}
//
//	auto_ptr<T>& operator=(auto_ptr<T>& ap)
//	{
//		if (this != &ap)
//		{
//			if (_ptr)
//				delete _ptr;
//
//			_ptr = ap._ptr;
//			ap._ptr = NULL;
//		}
//		retutn *this;
//	}
//
//	~auto_ptr()
//	{
//		if (_ptr)
//		{
//			delete _ptr;
//		}
//	}
//
//	T& operator*()
//	{
//		return *_ptr;
//	}
//
//	T* operator->()
//	{
//		return _ptr;
//	}
//
//private:
//	T* _ptr;
//};


//shared_ptr
#include<mutex>

template<class T>
class shared_ptr
{
public:
	shared_ptr(T* ptr = nullptr)
		:_ptr(ptr)
		,_pRefCount(new int(1))
		,_pmtx(new mutex)
	{}

	shared_ptr(const shared_ptr<T>& sp)
		:_ptr(sp.ptr)
		, _pRefCount(sp._pRefCount)
		, _pmtx(sp._pmtx)
	{
		AddRef();
	}

	void AddRef()
	{
		_pmtx->lock();
		++(*pRefCount);
		_pmtx->unlock();
	}

	void Release()
	{
		_pmtx->lock();
		bool flag = false;
		if (--(*_pRefCount) == 0 && _ptr)
		{
			delete _ptr;
			delete _pRefCount;
			flag = true;
		}

		_pmtx->unlock();
		if (flag == true)
		{
			delete _pmtx;
		}
	}

	shared_ptr<T>& operator=(const shared_ptr<T>& sp)
	{
		if (_ptr != sp._ptr)
		{
			Release();
			_ptr = sp._ptr;
			_pRefCount = sp._pRefCount;
			_pmtx = sp._pmtx;
			AddRef();
		}
		return *this;
	}

	T* operator->()
	{
		return _ptr;
	}

	T& operator*()
	{
		return *_ptr;
	}

	~shared_ptr()
	{
		Release();
	}
private:
	T* _ptr;
	int* _pRefCount;
	mutex* _pmtx;
};

